﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2012-04-13
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


//----------------------------------------------------------------
//
//----------------------------------------------------------------
#define FSTRUCT_MEMBER(_Ty, mb) ((size_t)&((_Ty*)0)->mb)
#define FSTRUCT_ADDR(_Ty, mb)   ((_Ty*)((BYTE*)mb - FSTRUCT_MEMBER(_Ty, mb)))


//----------------------------------------------------------------
// PI和常数相关
//----------------------------------------------------------------
const int   F_INVALID_IDX       = -1;
const float F_PI                = 3.14159265358979323846f;  // PI
const float F_PI2               = 1.57079632679489661923f;  // PI/2
const float F_PI4               = 0.78539816339744830961f;  // PI/4
const float F_PI6666            = 0.47123890275085801328f;  // PI/6.6666666
const float F_PID               = 6.28318530717958647692f;  // PI*2
const float F_1BYPI             = 0.31830988618379067154f;  // 1/PI
const float F_PI2R              = 0.01745329251994329577f;  // PI/180.0f
const float F_PI18              = 0.17453292519943295769f;  // PI/18.0f
const float F_PI2D              = 57.2957795130823208768f;  // 180.0f/PI
const float F_1BY255            = 0.00392156862745098039f;  // 1/255.0f
const float F_1BY65535          = 1.525902189669642e-5f;    // 1/65535.0f
const int   F_DEFAULT_FREQ      = 30;
const float F_FLT_MAX           = 3.402823466e+38F;         // float max value
const float F_FLT_MIN           = 1.175494351e-38F;         // float min positive value
const float F_EPSILON           = 1.0f / 64.0f;


//----------------------------------------------------------------
//
//----------------------------------------------------------------
enum EF_CONST_DATA_CORE
{
	eCD_MinName             = 4,            // 骨骼、节点、对象、地形、地图、动作、皮肤等名字最小长度（范围：0-0xFF）
	eCD_MaxName             = 32,           // 骨骼、节点、对象、地形、地图、动作、皮肤等名字最大长度（范围：0-0xFF）
	eCD_MinFilename         = 8,            // 贴图、模型、精灵等文件名字最小长度（范围：0-0xFF）
	eCD_MaxFilename         = 90,           // 贴图、模型、精灵等文件名字最大长度（范围：0-0xFF）

    eCD_MaxSubVM                = 12288,    // 虚拟内存查看时，单个内存区中最大子节点数量
#if FUEL_OS_WINDOWS
#ifdef _DEBUG
    eCD_MaxCallDepth            = 24,       // 函数调用堆栈查看最大深度
#else
    eCD_MaxCallDepth            = 12,       // 函数调用堆栈查看最大深度
#endif
#else
    eCD_MaxCallDepth            = 1,        // 函数调用堆栈查看最大深度
#endif
    eCD_MaxFuncName             = 240,      // 函数名最大长度
    eCD_MaxMemThread            = 128,      // 内存分配器最大支持线程数量
    eCD_IdleMemThread           = 1,        // 空闲中的线程内存池
    eCD_MaxThreadIO             = 2,        // 每个线程最大IO缓存数量
    eCD_MS_CODE                 = 0x3C,     // 转码
    eCD_MaxFiltrate             = 5,        // 最大支持字符过滤器数量
    eCD_PF_MaxMemInx            = 64,       // 最大保留64条内存增量信息
    eCD_MD5_MAX                 = 16,       // MD5结果尺寸

    EF_CONST_DATA_CORE_FORCE = 0xffffffff
};


//----------------------------------------------------------------
// 线程命令，其它命令由游戏自定义，且不能与以下命令重复
//----------------------------------------------------------------
enum EF_THREAD_COMMAND
{
    eTC_Run,                            // 运行线程
    eTC_Pause,                          // 暂停线程
    eTC_Exit,                           // 退出线程

    EF_THREAD_COMMAND_FORCE = 0xFF
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
enum EF_ASSERT_FLAGS
{
    eAF_ToFile                  = 1<<0, // Save To File         : 打印到log文件
    eAF_Console                 = 1<<1, // FOutDebugString      : 输出到调试控制台
    eAF_MessageBox              = 1<<3, // MessageBox           : 弹出对话框
    eAF_Break                   = 1<<4, // Breakpoints          : 抛出一个断点
    eAF_FileAndLine             = 1<<5, // File and line        : 打印的时候连文件位置和行号一起打印，以及函数名

    eAF_None                    = 0,    // null                 : 不输出到任何位置(FAssertLog、AssertFmt忽略此标记)
    eAF_All                     = 0xFFFFFFFF, //                : 全部启用

    eAF_Format                  = 0x800 // FAssertFmt 内存初始化大小
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
enum EF_ENCODE_MODE
{
    eEM_ANSI,                           // WINDOWS 平台下默认多字节
    eEM_UTF8,                           // ANDROID、LINUX、IOS 平台下默认多字节
    eEM_UTF16LE,                        // WINDOWS 平台下默认宽字节，也称为UNICODE
    eEM_UTF16BE,                        // 大头的宽字节，不常用
    eEM_UTF32LE,                        // ANDOIRD、LINUX、IOS 平台下默认宽字节
    eEM_UTF32BE,

    eEM_MAX,
};


//----------------------------------------------------------------
// 服务对象事件一些默认事件，其它事件由游戏自定义，且从eSE_User开始，不能与预定事件重复
//----------------------------------------------------------------
enum EF_SERVE_EVENT
{
    eSE_TidyMemory,                     // 整理内存事件（p0:无用，p1:无用）

    eSE_User                    = 0x100,// 用户事件开始

    EF_SERVE_EVENT_FORCE = 0xFFFFFFFF
};


//----------------------------------------------------------------
// 实体对象的默认属性，其它的属性由游戏自定义，且不能与以下码位属性重复
//----------------------------------------------------------------
enum EF_ENTITY_PROPERTY
{
    eEP_Enable                  = 1<<0,     // 可用的
    eEP_Visable                 = 1<<1,     // 可见的
    eEP_NeedUpdate              = 1<<2,     // 需要更新

    eEP_Default = eEP_Enable|eEP_Visable,

    EF_ENTITY_PROPERTY_FORCE = 0xFFFFFFFF
};


//----------------------------------------------------------------
// 文件对象的默认属性，其它的属性由游戏自定义，且不能与以下码位属性重复
//----------------------------------------------------------------
enum EF_FILE_PROPERTY
{
    eFP_Register                = 1<<0,     // 是通过注册产生的资源（此类资源释放的时候仅消毁资源数据，不删除对象）
    eFP_FileResource            = 1<<1,     // 是个文件资源
    eFP_DiySize                 = 1<<2,     // 是个自定义尺寸资源
    eFP_Locking                 = 1<<3,     // 被锁定中（能够被锁定）
    eFP_ThreadCreate            = 1<<4,     // 线程加载队列中
    eFP_Solidify                = 1<<5,     // 常用资源，不能消毁，直到程序结束
    eFP_Created                 = 1<<6,     // 已创建并加载完成
    eFP_CantCreate              = 1<<7,     // 如果文件不存在或者其它不能加载的原因有此标记
    eFP_CubeTexture             = 1<<8,     // 是立方贴图

    eFP_Default = 0,

    EF_FILE_PROPERTY_FORCE = 0xFFFFFFFF
};


//----------------------------------------------------------------
// 文件格式
//----------------------------------------------------------------
enum EF_IMAGE_FORMAT
{
    eIF_PNG,                                // PNG图片
    eIF_JPG,                                // JPG图片
    eIF_DDS,                                // DDS图片

    eIF_MAX,

    EF_IMAGE_FORMAT_FORCE = 0xFFFFFFFF
};


//----------------------------------------------------------------
// 测试碰撞（距离必然返回）
//----------------------------------------------------------------
enum EF_HIT_TYPE
{
    eHT_Position                = 1<<0,             // 要求返回碰撞点坐标
    eHT_Normal                  = 1<<1,             // 要求返回碰撞点的法线
    eHT_TwoSide                 = 1<<2,             // 要求双面都检查
    eHT_Triangle                = 1<<3,             // 要求返回该三角形

    eHT_Default = eHT_Position,
    eHT_All = 0xffff,

    EF_HIT_TYPE_FORCE = 0xFFFF
};


//----------------------------------------------------------------
// 相交类型
//----------------------------------------------------------------
enum EF_INTERSECTION_TYPE
{
    eIT_Back,                               // 在背面
    eIT_Front,                              // 在正面
    eIT_Intersection,                       // 相交了

    EF_INTERSECTION_TYPE_FORCE = 0xFF
};


//----------------------------------------------------------------
// 视锥平面类型
//----------------------------------------------------------------
enum EF_PLANE_FACE_TYPE
{
    ePFT_NEAR,
    ePFT_FAR,
    ePFT_LEFT,
    ePFT_RIGHT,
    ePFT_TOP,
    ePFT_BOTTOM,

    ePFT_MAX,

    EF_PLANE_FACE_TYPE_FORCE = 0xff
};


//----------------------------------------------------------------
// 动画模式
//----------------------------------------------------------------
enum EF_ANIMATE_MODE
{
    eAM_Loop,                               // 顺序循环（默认）
    eAM_StopFirst,                          // 顺序结束后停在顺序首帧
    eAM_StopLast,                           // 顺序结束后停在顺序尾帧
    eAM_Pinpong,                            // 交替循环
    eAM_ReLoop,                             // 反向循环
    eAM_ReStopFirst,                        // 反向结束后停在顺序首帧
    eAM_ReStopLast,                         // 反向结束后停在顺序尾帧
    eAM_SingleFirst,                        // 固定在顺序首帧
    eAM_SingleLast,                         // 固定在顺序尾帧
    eAM_Single,                             // 固定在指定帧

    EF_ANIMATE_MODE_FORCE = 0xff
};


//----------------------------------------------------------------
// 压缩与解压类型
//----------------------------------------------------------------
enum EF_COMPRESS_TYPE
{
    eCT_ZLIB,                               // zip
    eCT_LZMA,                               // 7z
    eCT_LZO,                                // lzo

    EF_COMPRESS_TYPE_FORCE = 0xff
};


//----------------------------------------------------------------
// 忽略与匹配模式
//----------------------------------------------------------------
enum EF_IGNORE_MATCH_MODE
{
    eIMM_IGN_DIR                = 1<<0, // 出现在目录列表的目录被忽略（包括该目录的子目录）
    eIMM_IGN_EXT                = 1<<1, // 出现在文件扩展名列表的文件被忽略
    eIMM_MAT_DIR                = 1<<3, // 出现在目录列表的目录被添加（不包含该目录的子目录）
    eIMM_MAT_EXT                = 1<<4, // 出现在文件扩展名列表的文件被添加

    eIMM_IGNORE = eIMM_IGN_DIR|eIMM_IGN_EXT,
    eIMM_MATCH = eIMM_MAT_DIR|eIMM_MAT_EXT,

    EF_IGNORE_MATCH_MODE_FROCE = 0xffffffff
};


//----------------------------------------------------------------
// lua 对象在初始化时的库选项
//----------------------------------------------------------------
enum EF_LUA_INIT_LIB
{
    eLIL_LUA                    = 1<<0,     // lua 标准库
    eLIL_FGE_CORE               = 1<<16,    // Fuel4D 核心库，API空间名：fge.core.[XXX]
    eLIL_FGE_UI                 = 1<<17,    // Fuel4D UI 库，API空间名：fge.ui.[XXX]

    eLIL_NORMAL = eLIL_LUA,
    eLIL_FGE = eLIL_FGE_CORE|eLIL_FGE_UI,
    eLIL_ALL = 0xffffffff,
};


//-----------------------------------------------------------------
// 性能分析对象类型
//-----------------------------------------------------------------
enum EF_PF_TYPE
{
    ePFT_FUNC,                                  // 1.函数调用消耗统计
    ePFT_MEM_INC,                               // 2.进程内存增量（需要每帧顶部调用FPF_GetService()->Idle()接口）
    ePFT_FPS,                                   // 3.FPS统计（需要每帧顶部调用FPF_GetService()->Idle()接口）

    ePFT_COUNT,                                 // 总共有多少种性能计数器
};


//-----------------------------------------------------------------
// 内存整理类型
//-----------------------------------------------------------------
enum EF_MEMORY_TIDY_TYPE
{
    eMTT_Memory                 = 1<<0,     // Fuel4D 内存池（FNew、FAlloc中出来的内存）
    eMTT_ObjFactory             = 1<<1,     // 对象仓库

    eMTT_All = 0xffff,                          // 整理全部

    EF_MEMORY_TIDY_FORCE = 0xffff
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
enum EF_FVF
{
    eFVF_Unknown                = 0,

    eFVF_XYZ                    = 1<<1,
    eFVF_XYZRHW                 = 1<<2,
    eFVF_XYZW                   = 1<<3,
    eFVF_NORMAL                 = 1<<4,
    eFVF_DIFFUSE                = 1<<5,
    eFVF_TEX1                   = 1<<6,

    EF_FVF_FORCE = 0xFFFFFFFF
};


//----------------------------------------------------------------
// FUEL_RENDER_STREAM_FLOAT16 打开情况下使用后面的渲染流格式
//----------------------------------------------------------------
enum EF_STREAM_TYPE
{
    eST_POSITION,                           // 位置 :FLOAT[3] / FLOAT16[4]
    eST_NORMAL,                             // 法线 :FLOAT[3] / FLOAT16[4]
    eST_COLOR,                              // 颜色 :BYTE [4] / BYTE   [4]
    eST_UV,                                 // UV   :FLOAT[2] / FLOAT16[2]
    eST_TANGENT,                            // 切线 :FLOAT[3] / FLOAT16[4]
    eST_BLENDINX,                           // 索引 :BYTE [4] / BYTE   [4]
    eST_BLENDWEIGHT2,                       // 权重 :FLOAT[2] / FLOAT16[2]
    eST_BLENDWEIGHT4,                       // 权重 :FLOAT[4] / FLOAT16[4]

    eST_Max,
};


//----------------------------------------------------------------
// 网络请求时返回的错误
//----------------------------------------------------------------
enum EF_HTTP_REQ_RESULT
{
    eHRR_OK,                    // 成功    
    eHRR_FAIL,                  // 失败
    eHRR_UNKNOWN,               // 未定义协议
    eHRR_TIMEOUT,               // 请求超时
    eHRR_CANTRESOLVE,           // 不能解析地址
    eHRR_CANTCONNECT,           // 不能连接
    eHRR_ERROR,                 // HTTP请求的数据错误

    EF_HTTP_REQ_RESULT_FORCE = 0xFFFFFFFF
};

enum EF_NET_CONNECT_RESULT
{
    eNCR_OK,                    // 启动连接器成功
    eNCR_NO_INIT,               // 请先调用Initialize
    eNCR_RE_CONNECT,            // 已经正在连接中
    eNCR_ALREADY_CONNECT,       // 已经有连接成功了
};

enum EF_NET_SOCKET_STATE
{
    eNST_NO_CONNECT,            // 还没有连接
    eNST_CONNECTING,            // 正在连接中
    eNST_CONNECT_OK,            // 连接正常（可收可接）
    eNST_CONNECT_FAIL,          // 做过连接动作，但连接失败了
    eNST_DISCONNECTING,         // 正在断开中
    eNST_IS_DISCONNECT,         // 曾经连接过，已被服务器主动断开
    eNST_SELF_DISCONNECT,       // 曾经连接过，是自己主动断开的
};


//----------------------------------------------------------------
// 根据平台变化的宏，主要用在格式化字符串方面
// 1. windows 平台默认使用UTF-16LE（UNICODE）
// 2. android、ios 平台默认使用UTF-8
//----------------------------------------------------------------
#if FUEL_OS_WINDOWS
#define FUEL_EC_ACHAR       eEM_ANSI
#define FUEL_EC_WCHAR       eEM_UTF16LE
#define FUEL_EC_TCHAR       eEM_UTF16LE
#define FUEL_DIR_DIVIDE     _FTW('\\')
#define FUEL_DIR_DIVIDEW    _FTW('\\')
#define FUEL_DIR_DIVIDEA    _FTA('\\')
#elif FUEL_OS_ANDROID
#define FUEL_EC_ACHAR       eEM_UTF8
#define FUEL_EC_WCHAR       eEM_UTF32LE
#define FUEL_EC_TCHAR       eEM_UTF8
#define FUEL_DIR_DIVIDE     _FTA('/')
#define FUEL_DIR_DIVIDEW    _FTW('/')
#define FUEL_DIR_DIVIDEA    _FTA('/')
#elif FUEL_OS_IOS
#define FUEL_EC_ACHAR       eEM_UTF8
#define FUEL_EC_WCHAR       eEM_UTF32LE
#define FUEL_EC_TCHAR       eEM_UTF8
#define FUEL_DIR_DIVIDE     _FTA('/')
#define FUEL_DIR_DIVIDEW    _FTW('/')
#define FUEL_DIR_DIVIDEA    _FTA('/')
#endif

//----------------------------------------------------------------
//
//----------------------------------------------------------------
#if FUEL_OS_WINDOWS
#define FPrintfW        wprintf_s
#define FPrintfA        printf_s
#define FScanfW         swscanf_s
#define FScanfA         sscanf_s
#else
#define FPrintfW        wprintf
#define FPrintfA        printf
#define FScanfW         swscanf
#define FScanfA         sscanf
#endif


//----------------------------------------------------------------
// 重写 STL 中 vector 和 map 容器的内存分配器，及期自动定义宏
//----------------------------------------------------------------
template < typename _Ty > class FAllocator;

#define typedef_vector(_Ty, _Name)\
    typedef std::vector< _Ty, FAllocator< _Ty > > fv##_Name

#define typedef_map(_Kty, _Ty, _Name)\
    typedef std::map< _Kty, _Ty, std::less< _Kty >, FAllocator< std::pair< _Kty, _Ty > > > fm##_Name

#define typedef_map_pr(_Kty, _Ty, _Pr, _Name)\
    typedef std::map< _Kty, _Ty, _Pr< _Kty >, FAllocator< std::pair< _Kty, _Ty > > > fm##_Name

#define typedef_list(_Ty, _Name)\
    typedef std::list< _Ty, FAllocator< _Ty > > fl##_Name

#define typedef_deque(_Ty, _Name)\
    typedef std::deque< _Ty, FAllocator< _Ty > > fd##_Name

#define typedef_stack(_Ty, _Name)\
    typedef std::stack< _Ty, std::deque< _Ty, FAllocator< _Ty > > > fs##_Name

#define std_end std::endl


//----------------------------------------------------------------
//
//----------------------------------------------------------------
#ifdef UNICODE
#define FScanf          FScanfW
#else
#define FScanf          FScanfA
#endif
#if FUEL_OS_WINDOWS
#define FFScanf         FScanfW
#else
#define FFScanf         FScanfW
#endif
